﻿// -----------------------------------------------------------------------
// <copyright file="InOutService.cs" company="FCIS">
// You are welcome to do whatever you want with the code in this file
// </copyright>
// -----------------------------------------------------------------------

namespace ImagePackage.IO
{
    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using Utilities;

    /// <summary>
    /// A default implementation for the IInOutService
    /// </summary>
    public class InOutService : IInOutService
    {
        /// <summary>
        /// Opens the specified image path.
        /// </summary>
        /// <param name="imagePath">The image path.</param>
        /// <returns>the image object</returns>
        public Model.Image Open(string imagePath)
        {
            try
            {
                Logger.Debug("Start opening file " + imagePath);
                if (File.Exists(imagePath))
                {
                    FileInfo fi = new FileInfo(imagePath);
                    if (fi.Extension == ".ppm")
                    {
                        PpmHandler ppmHandler = new PpmHandler();
                        return ppmHandler.Decode(imagePath);
                    }
                    else
                    {
                        // Create source.
                        BitmapImage bi = new BitmapImage();
                        //// BitmapImage.UriSource must be in a BeginInit/EndInit block.
                        bi.BeginInit();
                        bi.UriSource = new Uri(imagePath, UriKind.RelativeOrAbsolute);
                        bi.EndInit();

                        BitmapSource source = bi;
                        if (source.Format != PixelFormats.Bgra32)
                        {
                            source = new FormatConvertedBitmap(bi, PixelFormats.Bgra32, null, 0);
                        }

                        Model.Image image = new Model.Image(source.PixelWidth, source.PixelHeight);

                        int stride = source.PixelWidth * 4;

                        byte[] rawPixels = new byte[source.PixelWidth * source.PixelHeight * 4];
                        source.CopyPixels(rawPixels, stride, 0);
                        image.RawPixels = rawPixels;
                        return image;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogException("Something wrong happened while opening file", ex);
                throw;
            }
            finally
            {
                Logger.Debug("Finished opening file");
            }

            throw new Exception("File doesn't exist");
        }

        /// <summary>
        /// Saves the specified image path.
        /// </summary>
        /// <param name="image">The image model. </param>
        /// <param name="imagePath">The image path.</param>
        public void Save(Model.Image image, string imagePath)
        {
            Bitmap bitmap = new Bitmap(image.Width, image.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            BitmapData bitmapData = bitmap.LockBits(new Rectangle(new Point(), bitmap.Size), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            // Copy the bytes to the bitmap object
            Marshal.Copy(image.RawPixels, 0, bitmapData.Scan0, image.RawPixels.Length);
            bitmap.UnlockBits(bitmapData);

            bitmap.Save(imagePath, ImageFormat.Bmp);
        }
    }
}